﻿using System;
using System.Collections.Generic;


namespace BizElements.BusinessLayer
{
    /// <summary>
    /// A field whose begin and end values users can change to create a dynamic filter.
    /// </summary>
    public interface ISearchEngineField : IBindableField
    {
        #region Meta - field configuration.

        /// <summary>
        /// Indicates that the field should be automatically populated by application. 
        /// User shouldn't be allowed to enter arbitrary values.
        /// </summary>
        bool IsAutoPopulated { get; set; }

        /// <summary>
        /// Indicates whether interval search is allowed for this field.
        /// </summary>
        /// <remarks>When set to <b>false</b> the <see cref="EndValue"/> and <see cref="Values"/> properties
        /// are ignored. UI layer shouldn't allow users to enter end values if interval search is not supported.</remarks>
        bool AllowIntervalSearch { get; set; }

        /// <summary>
        /// Indicates whether arbitrary values are allowed.
        /// </summary>
        /// <remarks>When set to <b>false</b> the UI layer shouldn't allow users to enter arbitrary begin values.
        /// However, the engine should provide some other mechanism which enables user's to set values or 
        /// intervals, eg. <see cref="IBindableField.CodeList"/> or <see cref="ValueSets"/>.</remarks>
        bool AllowArbitraryBeginValue { get; set; }

        /// <summary>
        /// Indicates whether a user may specify multiple values to search for through <see cref="Values"/> property.
        /// </summary>
        bool AllowMultipleValues { get; set; }

        /// <summary>
        /// Gets a collection of predefined sets of values/intervals for this field.
        /// </summary>
        IList<INamedValueSet> ValueSets { get; }

        /// <summary>
        /// Specifies which text search modes are available to the user.
        /// </summary>
        TextSearchMode[] AllowedTextSearchModes { get; }

        /// <summary>
        /// Builds engine which searches for allowed field values.
        /// </summary>
        ISearchEngineBuilder LookupBuilder { get; }

        /// <summary>
        /// Specifies use cases for the current field.
        /// </summary>
        SearchFieldUsage Usage { get; set; }

        #endregion

        #region Values - user entry.

        /// <summary>
        /// Value to search for in the data-source.
        /// </summary>
        object BeginValue { get; set; }

        /// <summary>
        /// End value of the interval to search for in the data-source.
        /// </summary>
        object EndValue { get; set; }

        /// <summary>
        /// Values to search for in the data-source. If this property is set then <see cref="BeginValue"/>
        /// and <see cref="EndValue"/> properties are ignored.
        /// </summary>
        object[] Values { get; set; }

        /// <summary>
        /// Indicates whether to return only records where the field value is not set, ie. <b>null</b>.
        /// </summary>
        /// <remarks>If this property is set to <b>true</b> then <see cref="BeginValue"/>, <see cref="EndValue"/> and <see cref="Values"/> properties are ignored.</remarks>
        bool IsNull { get; set; }

        /// <summary>
        /// Indicates whether the filter created for this field is inverted.
        /// </summary>
        /// <remarks>Eg. all values except those in the interval defined by <see cref="BeginValue"/>
        /// and <see cref="EndValue"/> properties match the filter.</remarks>
        bool Negate { get; set; }

        /// <summary>
        /// Indicates whether the filter created for this field is combined using logical OR.
        /// </summary>
        bool AddWithOr { get; set; }

        /// <summary>
        /// Gets or sets the key (see <see cref="INamedValueSet.Key"/>) of a selected value set.
        /// </summary>
        string SelectedValueSetKey { get; set; }

        /// <summary>
        /// Gets or sets which of the allowed <see cref="TextSearchMode"/> to use when creating a filter.
        /// </summary>
        TextSearchMode SelectedTextSearchMode { get; set; }

        #endregion
    }
}